package gui.customizer.panes.netfilter;

import java.io.IOException;
import java.util.HashMap;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTextField;

import net.miginfocom.swing.MigLayout;
import core.models.NatRule;

public class Redirection extends NatConfigurable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5885356533601547583L;
	private JTextField txtSource;
	private JTextField txtDestination;
	private JTextField txtDestinationPort;
	private JTextField txtServerPort;
	private JCheckBox chckbxSource;
	private JCheckBox chckbxDestination;
	private JComboBox cmbInterface;
	private JComboBox cmbProtocol;

	/**
	 * Create the panel.
	 */
	public Redirection() {
		setLayout(new MigLayout("", "[grow][][grow][]", "[][]20[][]20[][]20[][]15[]"));
		
		JLabel lblSource = new JLabel("Source");
		add(lblSource, "cell 0 0");
		
		JLabel lblDestination = new JLabel("Destination");
		add(lblDestination, "cell 2 0");
		
		txtSource = new JTextField();
		add(txtSource, "cell 0 1,growx");
		txtSource.setColumns(10);
		
		chckbxSource = new JCheckBox("!");
		add(chckbxSource, "cell 1 1");
		
		txtDestination = new JTextField();
		add(txtDestination, "cell 2 1,growx");
		txtDestination.setColumns(10);
		
		chckbxDestination = new JCheckBox("!");
		add(chckbxDestination, "cell 3 1");
		
		JLabel lblInterface = new JLabel("Interface");
		add(lblInterface, "cell 0 2");
		
		cmbInterface = new JComboBox();
		add(cmbInterface, "cell 0 3,growx");
		try {
			cmbInterface.setModel(getAvailableInterfaces());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		JLabel lblProtocol = new JLabel("Protocol");
		add(lblProtocol, "cell 0 4");
		
		cmbProtocol = new JComboBox();
		add(cmbProtocol, "cell 0 5,growx");
		cmbProtocol.setModel(new DefaultComboBoxModel(new String[] { "tcp", "udp", "-none" }));
		
		JLabel lblDestinationPort = new JLabel("Destination Port");
		add(lblDestinationPort, "cell 0 6");
		
		JLabel lblServerPort = new JLabel("Server Port");
		add(lblServerPort, "cell 2 6");
		
		txtDestinationPort = new JTextField();
		add(txtDestinationPort, "cell 0 7,growx");
		txtDestinationPort.setColumns(10);
		
		txtServerPort = new JTextField();
		add(txtServerPort, "cell 2 7,growx");
		txtServerPort.setColumns(10);
		
		btnAdd = new JButton("Add");
		add(btnAdd, "cell 0 8");

	}

	@Override
	public void setRule(NatRule rule) {
		HashMap<String, String> options = rule.getOptions();
		
		if (options.containsKey("-s")) {
			txtSource.setText(options.get("-s"));
			chckbxSource.setSelected(false);
		} else if (options.containsKey("! -s")) {
			txtSource.setText(options.get("! -s"));
			chckbxSource.setSelected(true);
		} else {
			txtSource.setText("");
			chckbxSource.setSelected(false);
		}
		
		// Destination
		if (options.containsKey("-d")) {
			txtDestination.setText(options.get("-d"));
			chckbxDestination.setSelected(false);
		} else if (options.containsKey("! -d")) {
			txtDestination.setText(options.get("! -d"));
			chckbxDestination.setSelected(true);
		} else {
			txtDestination.setText("");
			chckbxDestination.setSelected(true);
		}
		
		// Interface
		if (options.containsKey("-i"))
			cmbInterface.setSelectedItem(options.get("-i"));
		else
			cmbInterface.setSelectedItem("-none");
		
		// Protocol
		if (options.containsKey("-p")) {
			cmbProtocol.setSelectedItem(options.get("-p"));
		} else {
			cmbProtocol.setSelectedItem("-none-");
		}
		
		// Source Port
		if (options.containsKey("-m tcp") || options.containsKey("-m udp")) {
			String value = options.containsKey("-m tcp") ? options.get("-m tcp") : options.get("-m udp");
			String[] elements = value.split(" ");
			if (elements.length == 2 && elements[0].equals("--dport")) {
				txtDestinationPort.setText(elements[1]);
			}
		} else {
			txtDestinationPort.setText("");
		}
		
		// Destination Port
		String target[] = options.get("-j").split(" ");
		if (target.length == 3 && target[0].equals("REDIRECT") && target[1].matches("--to(-ports)?")) {
			txtServerPort.setText(target[2]);
		} else {
			txtServerPort.setText("");
		}
	}

	@Override
	public NatRule getRule() {
		NatRule rule = new NatRule("-A", "PREROUTING");
		
		// Source
		if (!txtSource.getText().equals("")) {
			if (chckbxSource.isSelected())
				rule.addOption("! -s", txtSource.getText());
			else
				rule.addOption("-s", txtSource.getText());
		}
		
		// Destination
		if (!txtDestination.getText().equals("")) {
			if (chckbxDestination.isSelected())
				rule.addOption("! -d", txtDestination.getText());
			else
				rule.addOption("-d", txtDestination.getText());
		}
		
		// Interface
		if (!cmbInterface.getSelectedItem().equals("-none-")) {
			rule.addOption("-i", (String) cmbInterface.getSelectedItem());
		}
		
		// Protocol
		if (!cmbProtocol.getSelectedItem().equals("-none-")) {
			rule.addOption("-p", (String) cmbProtocol.getSelectedItem());
			
			if (!txtDestinationPort.equals("")) {
				rule.addOption("-m " + (String) cmbProtocol.getSelectedItem(), "--dport " + txtDestinationPort.getText());
			}
		}
		
		if (!txtServerPort.equals("")) {
			rule.addOption("-j", "REDIRECT --to-ports " + txtServerPort.getText());
		}
		
		return rule;
	}

	@Override
	public void resetFields() {
		txtSource.setText("");
		chckbxSource.setSelected(false);
		txtDestination.setText("");
		chckbxDestination.setSelected(false);
		
	}

}
